home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / ungepackte_daten / 1993 / 5 / 04b / funktionsplotter / fplotter.ampk / Renderer / TXT / OFunctions.mod < prev    next >
Encoding:
Text File  |  1995-06-01  |  41.8 KB  |  1,703 lines

  1. |##########|
  2. |#MAGIC   #|BOPDNEAN
  3. |#PROJECT #|"OFunctions"
  4. |#PATHS   #|"Project2.0"
  5. |#FLAGS   #|xx-x-x--x---xxx-----------------
  6. |#USERSW  #|--------------------------------
  7. |#USERMASK#|--------------------------------
  8. |#SWITCHES#|x----x----------
  9. |##########|
  10. $$TypeChk:=FALSE
  11. IMPLEMENTATION MODULE OFunctions;
  12.  
  13. FROM Resources   IMPORT ContextPtr,New,Dispose;
  14. FROM Exceptions  IMPORT DivisionByZero,RangeViolation;
  15. FROM Conversions IMPORT StringToReal,RealToString;
  16. FROM Strings     IMPORT Append;
  17. FROM Str         IMPORT CapsEqual;
  18.  
  19. IMPORT OLists,ODictionaries;
  20.  
  21. TYPE
  22.   Variable        = POINTER TO VariableObj;
  23.   Expression      = POINTER TO ExpressionObj;
  24.  
  25. DEFINITION MODULE ExLists = OLists.BiLists(Expression);
  26.  
  27.  
  28. TYPE
  29.   ExpressionObj   = OBJECT OF ExLists.Node;
  30.                       CONSTRUCTOR Create(func : Function):Expression;
  31.                       DESTRUCTOR Delete;
  32.                       DEFERRED METHOD FClone(func : Function):Expression;
  33.  
  34.                       DEFERRED METHOD Eval():LONGREAL;
  35.                       DEFERRED METHOD Compile;
  36.                       DEFERRED METHOD Diff(func  : Function;
  37.                                            after : Variable):Expression;
  38.  
  39.                       DEFERRED METHOD AppendOn(VAR str : STRING);
  40.                       DEFERRED METHOD StringLen():INTEGER;
  41.                       $$OwnHeap:=TRUE
  42.                       METHOD toString():STRING;
  43.                     END;
  44.  
  45.   Constant        = POINTER TO OBJECT OF Expression;
  46.                       value : LONGREAL;
  47.                       CONSTRUCTOR Create(func  : Function;
  48.                                          value : LONGREAL):Expression;
  49.                       METHOD FClone(func : Function):Expression;
  50.  
  51.                       METHOD Eval():LONGREAL;
  52.                       METHOD Diff(func  : Function;
  53.                                   after : Variable):Expression;
  54.  
  55.                       METHOD AppendOn(VAR str : STRING);
  56.                       METHOD StringLen():INTEGER;
  57.                     END;
  58.  
  59.   ExpressionList  = POINTER TO OBJECT OF Expression,ExLists.List;
  60.                       DESTRUCTOR Delete;
  61.                       METHOD FClone(func : Function):Expression;
  62.                     END;
  63.  
  64.  
  65.   Summation       = POINTER TO OBJECT OF ExpressionList;
  66.                       METHOD Diff(func  : Function;
  67.                                   after : Variable):Expression;
  68.                       METHOD Eval():LONGREAL;
  69.                       METHOD AppendOn(VAR str : STRING);
  70.                       METHOD StringLen():INTEGER;
  71.                     END;
  72.  
  73.   Product         = POINTER TO OBJECT OF ExpressionList;
  74.                       METHOD Diff(func  : Function;
  75.                                   after : Variable):Expression;
  76.                       METHOD Eval():LONGREAL;
  77.                       METHOD AppendOn(VAR str : STRING);
  78.                       METHOD StringLen():INTEGER;
  79.                     END;
  80.  
  81.   SimpleFunction  = POINTER TO OBJECT OF Expression;
  82.                       of : Expression;
  83.                       CONSTRUCTOR Create(func : Function;
  84.                                          of   : Expression):Expression;
  85.                       DESTRUCTOR Delete;
  86.                       METHOD FClone(func : Function):Expression;
  87.                     END;
  88.  
  89.   Negation        = POINTER TO OBJECT OF SimpleFunction;
  90.                       METHOD Diff(func  : Function;
  91.                                   after : Variable):Expression;
  92.                       METHOD Eval():LONGREAL;
  93.                       METHOD AppendOn(VAR str : STRING);
  94.                       METHOD StringLen():INTEGER;
  95.                     END;
  96.  
  97.   Reciproke       = POINTER TO OBJECT OF SimpleFunction;
  98.                       METHOD Diff(func  : Function;
  99.                                   after : Variable):Expression;
  100.                       METHOD Eval():LONGREAL;
  101.                       METHOD AppendOn(VAR str : STRING);
  102.                       METHOD StringLen():INTEGER;
  103.                     END;
  104.  
  105.   VariableObj     = OBJECT OF Expression;
  106.                       value : LONGREAL;
  107.                       name  : STRING(20);
  108.                       METHOD Eval():LONGREAL;
  109.                       METHOD Diff(func  : Function;
  110.                                   after : Variable):Expression;
  111.                       CONSTRUCTOR Create(    func : Function;
  112.                                          REF name : STRING);
  113.                       METHOD FClone(func : Function):Expression;
  114.  
  115.                       METHOD AppendOn(VAR str : STRING);
  116.                       METHOD StringLen():INTEGER;
  117.                     END;
  118.  
  119.   Potenz          = POINTER TO OBJECT OF Expression;
  120.                       base,
  121.                       exponent : Expression;
  122.                       CONSTRUCTOR Create(func     : Function;
  123.                                          base,ex  : Expression):Expression;
  124.                       DESTRUCTOR Delete;
  125.                       METHOD FClone(func : Function):Expression;
  126.                       METHOD Diff(func  : Function;
  127.                                   after : Variable):Expression;
  128.  
  129.                       METHOD Eval():LONGREAL;
  130.                       METHOD AppendOn(VAR str : STRING);
  131.                       METHOD StringLen():INTEGER;
  132.                     END;
  133.  
  134.   Indirection     = POINTER TO OBJECT OF SimpleFunction;
  135.                       METHOD Diff(func  : Function;
  136.                                   after : Variable):Expression;
  137.                       DESTRUCTOR Delete;
  138.  
  139.                       METHOD Eval():LONGREAL;
  140.                       METHOD AppendOn(VAR str : STRING);
  141.                       METHOD StringLen():INTEGER;
  142.                     END;
  143.  
  144. DEFINITION MODULE VarDicts = ODictionaries.TextDicts(Variable);
  145.  
  146. TYPE
  147.   VarDict         = VarDicts.Dictionary;
  148.  
  149. PROCEDURE BuildSum(func       : Function;
  150.                    left,right : Expression):Expression;
  151.  
  152.   PROCEDURE AddToSum(prod  : Summation;
  153.                      const : Constant):Expression;
  154.   VAR ex : Expression;
  155.   BEGIN
  156.     ex:=prod.first;
  157.     WHILE ex#NIL
  158.       AND_WHILE NOT (ex IS Constant) DO
  159.         ex:=ex.next
  160.       ELSE
  161.         Constant(ex).value:=Constant(ex).value+const.value;
  162.         const.Delete;
  163.         IF Constant(ex).value=0.0 THEN
  164.           prod.RemoveNode(ex);
  165.           IF prod.first=prod.last THEN
  166.             ex:=prod.first;
  167.             prod.RemoveNode(ex);
  168.             prod.Delete;
  169.             RETURN ex;
  170.           ELSE
  171.             RETURN prod
  172.           END;
  173.         ELSE
  174.           RETURN prod;
  175.         END;
  176.       END
  177.     ELSE
  178.       prod.InsertLast(const);
  179.       RETURN prod
  180.     END;
  181.   END AddToSum;
  182.  
  183.   PROCEDURE JoinSumms(left,right : Summation):Expression;
  184.   VAR const : Constant;
  185.       ex    : Expression;
  186.   BEGIN
  187.     ex:=left.first;
  188.     WHILE (ex#NIL) AND NOT (ex IS Constant) DO
  189.       ex:=ex.next;
  190.     END;
  191.     const:=ex;
  192.  
  193.     WHILE right.first#NIL DO
  194.       ex:=right.first;
  195.       right.RemoveNode(ex);
  196.       IF (const#NIL) AND (ex IS Constant) THEN
  197.         const.value:=const.value+Constant(ex).value;
  198.         ex.Delete;
  199.         IF const.value=0.0 THEN
  200.           left.RemoveNode(const);
  201.           const.Delete;
  202.           const:=NIL
  203.         END;
  204.       ELSE
  205.         left.InsertLast(ex)
  206.       END;
  207.     END;
  208.     right.Delete;
  209.     RETURN left;
  210.   END JoinSumms;
  211.  
  212. VAR sum : Summation;
  213. BEGIN
  214.   IF left IS Constant
  215.     AND_IF Constant(left).value=0.0 THEN
  216.       left.Delete;
  217.       RETURN right
  218.     OR_IF right IS Constant THEN
  219.       Constant(left).value:=Constant(left).value+Constant(right).value;
  220.       right.Delete;
  221.       RETURN left
  222.     END
  223.   OR_IF right IS Constant
  224.     AND_IF Constant(right).value=0.0 THEN
  225.       right.Delete;
  226.       RETURN left
  227.     END
  228.   OR_IF left IS Summation THEN
  229.     IF right IS Summation THEN
  230.       RETURN JoinSumms(left,right);
  231.     OR_IF right IS Constant THEN
  232.       RETURN AddToSum(left,right);
  233.     ELSE
  234.       Summation(left).InsertLast(right);
  235.       RETURN left
  236.     END
  237.   OR_IF right IS Summation THEN
  238.     IF left IS Constant THEN
  239.       RETURN AddToSum(right,left)
  240.     ELSE
  241.       Summation(right).InsertLast(left);
  242.       RETURN right
  243.     END
  244.   ELSE
  245.     sum:=Summation.Create(func);
  246.     sum.InsertLast(left);
  247.     sum.InsertLast(right);
  248.     RETURN sum
  249.   END;
  250. END BuildSum;
  251.  
  252. PROCEDURE BuildProduct(func       : Function;
  253.                        left,right : Expression):Expression;
  254.  
  255.   PROCEDURE AddToProduct(prod  : Product;
  256.                          const : Constant):Expression;
  257.   VAR ex : Expression;
  258.   BEGIN
  259.     ex:=prod.first;
  260.     WHILE ex#NIL
  261.       AND_WHILE NOT (ex IS Constant) DO
  262.         ex:=ex.next
  263.       ELSE
  264.         Constant(ex).value:=Constant(ex).value*const.value;
  265.         const.Delete;
  266.         IF Constant(ex).value=1.0 THEN
  267.           prod.RemoveNode(ex);
  268.           IF prod.first=prod.last THEN
  269.             ex:=prod.first;
  270.             prod.RemoveNode(ex);
  271.             prod.Delete;
  272.             RETURN ex;
  273.           ELSE
  274.             RETURN prod
  275.           END;
  276.         ELSE
  277.           RETURN prod;
  278.         END;
  279.       END
  280.     ELSE
  281.       prod.InsertLast(const);
  282.       RETURN prod
  283.     END;
  284.   END AddToProduct;
  285.  
  286.   PROCEDURE JoinProducts(left,right : Product):Expression;
  287.   VAR const : Constant;
  288.       ex    : Expression;
  289.   BEGIN
  290.     ex:=left.first;
  291.     WHILE (ex#NIL) AND NOT (ex IS Constant) DO
  292.       ex:=ex.next;
  293.     END;
  294.     const:=ex;
  295.  
  296.     WHILE right.first#NIL DO
  297.       ex:=right.first;
  298.       right.RemoveNode(ex);
  299.       IF (const#NIL) AND (ex IS Constant) THEN
  300.         const.value:=const.value*Constant(ex).value;
  301.         ex.Delete;
  302.         IF const.value=1.0 THEN
  303.           left.RemoveNode(const);
  304.           const.Delete;
  305.           const:=NIL
  306.         END;
  307.       ELSE
  308.         left.InsertLast(ex)
  309.       END;
  310.     END;
  311.     right.Delete;
  312.     RETURN left;
  313.   END JoinProducts;
  314.  
  315. VAR prod : Product;
  316.  
  317. BEGIN
  318.   IF left IS Constant
  319.     AND_IF Constant(left).value=0.0 THEN
  320.       right.Delete;
  321.       RETURN left
  322.     OR_IF Constant(left).value=1.0 THEN
  323.       left.Delete;
  324.       RETURN right
  325.     OR_IF right IS Constant THEN
  326.       Constant(left).value:=Constant(left).value*Constant(right).value;
  327.       right.Delete;
  328.       RETURN left;
  329.     END
  330.   OR_IF right IS Constant
  331.     AND_IF Constant(right).value=0.0 THEN
  332.       left.Delete;
  333.       RETURN right
  334.     OR_IF Constant(right).value=1.0 THEN
  335.       right.Delete;
  336.       RETURN left
  337.     END
  338.   OR_IF left IS Product THEN
  339.     IF right IS Product THEN
  340.       RETURN JoinProducts(left,right);
  341.     OR_IF right IS Constant THEN
  342.       RETURN AddToProduct(left,right)
  343.     ELSE
  344.       Product(left).InsertLast(right);
  345.       RETURN left;
  346.     END
  347.   OR_IF right IS Product THEN
  348.     IF left IS Constant THEN
  349.       RETURN AddToProduct(right,left)
  350.     ELSE
  351.       Product(right).InsertFirst(left);
  352.       RETURN right;
  353.     END;
  354.   ELSE
  355.     prod:=Product.Create(func);
  356.     prod.InsertLast(left);
  357.     prod.InsertLast(right);
  358.     RETURN prod;
  359.   END;
  360. END BuildProduct;
  361.  
  362.  
  363. TYPE
  364.   F_SIN      = POINTER TO OBJECT OF SimpleFunction;
  365.                  METHOD Eval():LONGREAL;
  366.                  METHOD Diff(func : Function;after : Variable):Expression;
  367.                  METHOD AppendOn(VAR str : STRING);
  368.                  METHOD StringLen():INTEGER;
  369.                END;
  370.  
  371.   F_COS      = POINTER TO OBJECT OF SimpleFunction;
  372.                  METHOD Eval():LONGREAL;
  373.                  METHOD Diff(func : Function;after : Variable):Expression;
  374.                  METHOD AppendOn(VAR str : STRING);
  375.                  METHOD StringLen():INTEGER;
  376.                END;
  377.  
  378.   F_EXP      = POINTER TO OBJECT OF SimpleFunction;
  379.                  METHOD Eval():LONGREAL;
  380.                  METHOD AppendOn(VAR str : STRING);
  381.                  METHOD StringLen():INTEGER;
  382.                END;
  383.  
  384.   F_SQRT      = POINTER TO OBJECT OF SimpleFunction;
  385.                  METHOD Eval():LONGREAL;
  386.                  METHOD AppendOn(VAR str : STRING);
  387.                  METHOD StringLen():INTEGER;
  388.                END;
  389.  
  390.   F_LOG      = POINTER TO OBJECT OF SimpleFunction;
  391.                  METHOD Eval():LONGREAL;
  392.                  METHOD AppendOn(VAR str : STRING);
  393.                  METHOD StringLen():INTEGER;
  394.                END;
  395.  
  396.   F_LN      = POINTER TO OBJECT OF SimpleFunction;
  397.                  METHOD Eval():LONGREAL;
  398.                  METHOD AppendOn(VAR str : STRING);
  399.                  METHOD StringLen():INTEGER;
  400.                END;
  401.  
  402.   F_TAN      = POINTER TO OBJECT OF SimpleFunction;
  403.                  METHOD Eval():LONGREAL;
  404.                  METHOD AppendOn(VAR str : STRING);
  405.                  METHOD StringLen():INTEGER;
  406.                END;
  407.  
  408.   F_ASIN      = POINTER TO OBJECT OF SimpleFunction;
  409.                  METHOD Eval():LONGREAL;
  410.                  METHOD AppendOn(VAR str : STRING);
  411.                  METHOD StringLen():INTEGER;
  412.                END;
  413.  
  414.   F_ACOS      = POINTER TO OBJECT OF SimpleFunction;
  415.                  METHOD Eval():LONGREAL;
  416.                  METHOD AppendOn(VAR str : STRING);
  417.                  METHOD StringLen():INTEGER;
  418.                END;
  419.  
  420.   F_ABS      = POINTER TO OBJECT OF SimpleFunction;
  421.                  METHOD Eval():LONGREAL;
  422.                  METHOD AppendOn(VAR str : STRING);
  423.                  METHOD StringLen():INTEGER;
  424.                END;
  425.  
  426.   F_SGN      = POINTER TO OBJECT OF SimpleFunction;
  427.                  METHOD Eval():LONGREAL;
  428.                  METHOD AppendOn(VAR str : STRING);
  429.                  METHOD StringLen():INTEGER;
  430.                END;
  431.  
  432.   F_ATAN      = POINTER TO OBJECT OF SimpleFunction;
  433.                  METHOD Eval():LONGREAL;
  434.                  METHOD AppendOn(VAR str : STRING);
  435.                  METHOD StringLen():INTEGER;
  436.                END;
  437.  
  438. METHOD F_SIN.Eval():LONGREAL;
  439. BEGIN
  440.   RETURN SIN(of.Eval());
  441. END Eval;
  442.  
  443. METHOD F_SIN.Diff(func : Function;after : Variable):Expression;
  444. BEGIN
  445.   RETURN BuildProduct(func,of.Diff(func,after),
  446.                            F_COS.Create(func,of.FClone(func)));
  447. END Diff;
  448.  
  449. METHOD F_SIN.AppendOn(VAR str : STRING);
  450. BEGIN
  451.   Strings.Append(str,"SIN(");
  452.   of.AppendOn(str);
  453.   Strings.Append(str,")");
  454. END AppendOn;
  455.  
  456. METHOD F_SIN.StringLen():INTEGER;
  457. BEGIN
  458.   RETURN "SIN".len+2+of.StringLen();
  459. END StringLen;
  460.  
  461.  
  462. METHOD F_COS.Eval():LONGREAL;
  463. BEGIN
  464.   RETURN COS(of.Eval());
  465. END Eval;
  466.  
  467. METHOD F_COS.Diff(func : Function;after : Variable):Expression;
  468. BEGIN
  469.   RETURN BuildProduct(func,of.Diff(func,after),
  470.                            Negation.Create(func,
  471.                              F_SIN.Create(func,of.FClone(func))));
  472. END Diff;
  473.  
  474. METHOD F_COS.AppendOn(VAR str : STRING);
  475. BEGIN
  476.   Strings.Append(str,"COS(");
  477.   of.AppendOn(str);
  478.   Strings.Append(str,")");
  479. END AppendOn;
  480.  
  481. METHOD F_COS.StringLen():INTEGER;
  482. BEGIN
  483.   RETURN "COS".len+2+of.StringLen();
  484. END StringLen;
  485.  
  486.  
  487. METHOD F_EXP.Eval():LONGREAL;
  488. BEGIN
  489.   RETURN EXP(of.Eval());
  490. END Eval;
  491.  
  492. METHOD F_EXP.AppendOn(VAR str : STRING);
  493. BEGIN
  494.   Strings.Append(str,"EXP(");
  495.   of.AppendOn(str);
  496.   Strings.Append(str,")");
  497. END AppendOn;
  498.  
  499. METHOD F_EXP.StringLen():INTEGER;
  500. BEGIN
  501.   RETURN "EXP".len+2+of.StringLen();
  502. END StringLen;
  503.  
  504.  
  505. METHOD F_SQRT.Eval():LONGREAL;
  506. BEGIN
  507.   RETURN SQRT(of.Eval());
  508. END Eval;
  509.  
  510. METHOD F_SQRT.AppendOn(VAR str : STRING);
  511. BEGIN
  512.   Strings.Append(str,"SQRT(");
  513.   of.AppendOn(str);
  514.   Strings.Append(str,")");
  515. END AppendOn;
  516.  
  517. METHOD F_SQRT.StringLen():INTEGER;
  518. BEGIN
  519.   RETURN "SQRT".len+2+of.StringLen();
  520. END StringLen;
  521.  
  522.  
  523. METHOD F_LOG.Eval():LONGREAL;
  524. BEGIN
  525.   RETURN LOG(of.Eval());
  526. END Eval;
  527.  
  528. METHOD F_LOG.AppendOn(VAR str : STRING);
  529. BEGIN
  530.   Strings.Append(str,"LOG(");
  531.   of.AppendOn(str);
  532.   Strings.Append(str,")");
  533. END AppendOn;
  534.  
  535. METHOD F_LOG.StringLen():INTEGER;
  536. BEGIN
  537.   RETURN "LOG".len+2+of.StringLen();
  538. END StringLen;
  539.  
  540.  
  541. METHOD F_LN.Eval():LONGREAL;
  542. BEGIN
  543.   RETURN LN(of.Eval());
  544. END Eval;
  545.  
  546. METHOD F_LN.AppendOn(VAR str : STRING);
  547. BEGIN
  548.   Strings.Append(str,"LN(");
  549.   of.AppendOn(str);
  550.   Strings.Append(str,")");
  551. END AppendOn;
  552.  
  553. METHOD F_LN.StringLen():INTEGER;
  554. BEGIN
  555.   RETURN "LN".len+2+of.StringLen();
  556. END StringLen;
  557.  
  558.  
  559. METHOD F_TAN.Eval():LONGREAL;
  560. BEGIN
  561.   RETURN TAN(of.Eval());
  562. END Eval;
  563.  
  564. METHOD F_TAN.AppendOn(VAR str : STRING);
  565. BEGIN
  566.   Strings.Append(str,"TAN(");
  567.   of.AppendOn(str);
  568.   Strings.Append(str,")");
  569. END AppendOn;
  570.  
  571. METHOD F_TAN.StringLen():INTEGER;
  572. BEGIN
  573.   RETURN "TAN".len+2+of.StringLen();
  574. END StringLen;
  575.  
  576.  
  577. METHOD F_ASIN.Eval():LONGREAL;
  578. BEGIN
  579.   RETURN ASIN(of.Eval());
  580. END Eval;
  581.  
  582. METHOD F_ASIN.AppendOn(VAR str : STRING);
  583. BEGIN
  584.   Strings.Append(str,"ASIN(");
  585.   of.AppendOn(str);
  586.   Strings.Append(str,")");
  587. END AppendOn;
  588.  
  589. METHOD F_ASIN.StringLen():INTEGER;
  590. BEGIN
  591.   RETURN "ASIN".len+2+of.StringLen();
  592. END StringLen;
  593.  
  594.  
  595. METHOD F_ACOS.Eval():LONGREAL;
  596. BEGIN
  597.   RETURN ACOS(of.Eval());
  598. END Eval;
  599.  
  600. METHOD F_ACOS.AppendOn(VAR str : STRING);
  601. BEGIN
  602.   Strings.Append(str,"ACOS(");
  603.   of.AppendOn(str);
  604.   Strings.Append(str,")");
  605. END AppendOn;
  606.  
  607. METHOD F_ACOS.StringLen():INTEGER;
  608. BEGIN
  609.   RETURN "ACOS".len+2+of.StringLen();
  610. END StringLen;
  611.  
  612.  
  613. METHOD F_ABS.Eval():LONGREAL;
  614. BEGIN
  615.   RETURN ABS(of.Eval());
  616. END Eval;
  617.  
  618. METHOD F_ABS.AppendOn(VAR str : STRING);
  619. BEGIN
  620.   Strings.Append(str,"ABS(");
  621.   of.AppendOn(str);
  622.   Strings.Append(str,")");
  623. END AppendOn;
  624.  
  625. METHOD F_ABS.StringLen():INTEGER;
  626. BEGIN
  627.   RETURN "ABS".len+2+of.StringLen();
  628. END StringLen;
  629.  
  630.  
  631. METHOD F_SGN.Eval():LONGREAL;
  632. VAR val : LONGREAL;
  633. BEGIN
  634.   val:=of.Eval();
  635.   IF val<0 THEN
  636.     RETURN -1.0
  637.   OR_IF val>0 THEN
  638.     RETURN 1.0
  639.   ELSE
  640.     RETURN 0.0
  641.   END;
  642. END Eval;
  643.  
  644. METHOD F_SGN.AppendOn(VAR str : STRING);
  645. BEGIN
  646.   Strings.Append(str,"SGN(");
  647.   of.AppendOn(str);
  648.   Strings.Append(str,")");
  649. END AppendOn;
  650.  
  651. METHOD F_SGN.StringLen():INTEGER;
  652. BEGIN
  653.   RETURN "SGN".len+2+of.StringLen();
  654. END StringLen;
  655.  
  656.  
  657. METHOD F_ATAN.Eval():LONGREAL;
  658. BEGIN
  659.   RETURN ATAN(of.Eval());
  660. END Eval;
  661.  
  662. METHOD F_ATAN.AppendOn(VAR str : STRING);
  663. BEGIN
  664.   Strings.Append(str,"ATAN(");
  665.   of.AppendOn(str);
  666.   Strings.Append(str,")");
  667. END AppendOn;
  668.  
  669. METHOD F_ATAN.StringLen():INTEGER;
  670. BEGIN
  671.   RETURN "ATAN".len+2+of.StringLen();
  672. END StringLen;
  673.  
  674.  
  675.  
  676. METHOD Expression.toString():STRING;
  677. VAR i : INTEGER;
  678. BEGIN
  679.   i:=SELF.StringLen();
  680.   ALLOC_RESULT(i+1);
  681.   ASSERT(i<RESULT'RANGE,RangeViolation);
  682.   RESULT:="";
  683.   SELF.AppendOn(RESULT);
  684. END toString;
  685.  
  686. METHOD Expression.Delete;BEGIN END Delete;
  687.  
  688. METHOD SimpleFunction.Delete;
  689. BEGIN
  690.   of.Delete;
  691. END Delete;
  692.  
  693. METHOD ExpressionList.Delete;
  694. BEGIN
  695.   SELF.DeleteAll;
  696. END Delete;
  697.  
  698. METHOD Potenz.Delete;
  699. BEGIN
  700.   base.Delete;
  701.   exponent.Delete;
  702. END Delete;
  703.  
  704. METHOD Potenz.FClone(func : Function):Expression;
  705. BEGIN
  706.   RETURN Potenz.Create(func,base.FClone(func),exponent.FClone(func));
  707. END FClone;
  708.  
  709. METHOD ExpressionList.FClone(func : Function):Expression;
  710. VAR sum : ExpressionList;
  711.     ex  : Expression;
  712. BEGIN
  713.   sum:=CLONE(SELF);sum.first:=NIL;sum.last:=NIL;
  714.   Resources.ChangeObjContext(sum,func.con);
  715.  
  716.   ex:=first;
  717.   WHILE ex#NIL DO
  718.     sum.InsertLast(ex.FClone(func));
  719.     ex:=ex.next;
  720.   END;
  721.   RETURN sum;
  722. END FClone;
  723.  
  724. METHOD SimpleFunction.FClone(func : Function):Expression;
  725. VAR f : SimpleFunction;
  726. BEGIN
  727.   f:=CLONE(SELF);
  728.   Resources.ChangeObjContext(f,func.con);
  729.   f.of:=of.FClone(func);
  730.   RETURN f;
  731. END FClone;
  732.  
  733. METHOD Expression.Create(func : Function):Expression;
  734. BEGIN
  735.   Resources.ChangeObjContext(SELF,func.con);
  736.   RETURN SELF;
  737. END Create;
  738.  
  739. METHOD Indirection.Eval():LONGREAL;
  740. BEGIN
  741.   RETURN of.Eval();
  742. END Eval;
  743.  
  744. METHOD Indirection.StringLen():INTEGER;
  745. BEGIN
  746.   RETURN of.StringLen();
  747. END StringLen;
  748.  
  749. METHOD Indirection.AppendOn(VAR str : STRING);
  750. BEGIN
  751.   of.AppendOn(str);
  752. END AppendOn;
  753.  
  754. METHOD Indirection.Diff(func  : Function;
  755.                         after : Variable):Expression;
  756. BEGIN
  757.   RETURN of.Diff(func,after);
  758. END Diff;
  759.  
  760. METHOD Indirection.Delete;BEGIN END Delete;
  761.  
  762.  
  763. METHOD Constant.Eval():LONGREAL;
  764. BEGIN
  765.   RETURN value
  766. END Eval;
  767.  
  768. METHOD Constant.Create(func  : Function;
  769.                        value : LONGREAL):Expression;
  770. BEGIN
  771.   SELF.value:=value;
  772.   RETURN SUPER.Create(func);
  773. END Create;
  774.  
  775. METHOD Constant.FClone(func : Function):Expression;
  776. BEGIN
  777.   RETURN Constant.Create(func,value);
  778. END FClone;
  779.  
  780. METHOD Constant.StringLen():INTEGER;
  781. BEGIN
  782.   RETURN 10;
  783. END StringLen;
  784.  
  785. METHOD Constant.AppendOn(VAR str : STRING);
  786. BEGIN
  787.   Strings.Append(str,RealToString(value,10,5));
  788. END AppendOn;
  789.  
  790. METHOD Constant.Diff(func : Function;after : Variable):Expression;
  791. BEGIN
  792.   RETURN Constant.Create(func,0.0);
  793. END Diff;
  794.  
  795. METHOD Variable.Eval():LONGREAL;
  796. BEGIN
  797.   RETURN value
  798. END Eval;
  799.  
  800. METHOD Variable.Diff(func : Function;after : Variable):Expression;
  801. BEGIN
  802.   IF SELF=after THEN
  803.     RETURN Constant.Create(func,1.0);
  804.   ELSE
  805.     RETURN Constant.Create(func,0.0);
  806.   END;
  807. END Diff;
  808.  
  809. METHOD Variable.StringLen():INTEGER;
  810. BEGIN
  811.   RETURN name.len;
  812. END StringLen;
  813.  
  814. METHOD Variable.AppendOn(VAR str : STRING);
  815. BEGIN
  816.   Strings.Append(str,name);
  817. END AppendOn;
  818.  
  819.  
  820. METHOD Summation.Eval():LONGREAL;
  821. VAR val : LONGREAL;
  822.     e   : Expression;
  823. BEGIN
  824.   val:=0.0;
  825.   e:=first;
  826.   WHILE e#NIL DO val:=val+e.Eval();e:=e.next END;
  827.   RETURN val;
  828. END Eval;
  829.  
  830. METHOD Summation.Diff(func : Function;after : Variable):Expression;
  831. VAR ex,dif : Expression;
  832.     const  : Constant   := NIL;
  833.     sum    : Summation  := NIL;
  834.     var    : Expression := NIL;
  835. BEGIN
  836.   ex:=first;
  837.   WHILE ex#NIL DO
  838.     dif:=ex.Diff(func,after);
  839.     IF dif IS Constant THEN
  840.       IF const#NIL THEN
  841.         const.value:=const.value+Constant(dif).value;
  842.         DISPOSE(dif);
  843.       ELSE
  844.         const:=dif
  845.       END;
  846.     OR_IF sum#NIL THEN
  847.       sum.InsertLast(dif);
  848.     OR_IF var#NIL THEN
  849.       sum:=Summation.Create(func);
  850.       sum.InsertLast(var);
  851.       sum.InsertLast(dif);
  852.     ELSE
  853.       var:=dif
  854.     END;
  855.     ex:=ex.next;
  856.   END;
  857.   IF (const#NIL) AND (const.value=0.0) AND ((sum#NIL) OR (var#NIL)) THEN
  858.     DISPOSE(const);const:=NIL;
  859.   END;
  860.   IF const=NIL THEN
  861.     IF sum#NIL THEN
  862.       RETURN sum
  863.     ELSE
  864.       RETURN var
  865.     END
  866.   ELSE
  867.     IF sum#NIL THEN
  868.       sum.InsertLast(const);
  869.       RETURN sum;
  870.     OR_IF var#NIL THEN
  871.       sum:=Summation.Create(func);
  872.       sum.InsertLast(var);
  873.       sum.InsertLast(const);
  874.       RETURN sum;
  875.     ELSE
  876.       RETURN const;
  877.     END;
  878.   END;
  879. END Diff;
  880.  
  881. METHOD Product.Diff(func : Function;after : Variable):Expression;
  882. VAR left,
  883.     right       : Expression;
  884.     ret         : Expression;
  885. BEGIN
  886.   left:=first;
  887.   IF first.next=last THEN
  888.     right:=last;
  889.   ELSE
  890.     SELF.RemoveNode(left);
  891.     right:=SELF;
  892.   END;
  893.   ret:=BuildSum(func,
  894.          BuildProduct(func,left.FClone(func),right.Diff(func,after)),
  895.          BuildProduct(func,left.Diff(func,after),right.FClone(func)));
  896.   IF left#first THEN
  897.     SELF.InsertFirst(left)
  898.   END;
  899.   RETURN ret;
  900. END Diff;
  901.  
  902. METHOD Summation.StringLen():INTEGER;
  903. VAR len : INTEGER;
  904.     ex  : Expression;
  905. BEGIN
  906.   len:=first.StringLen();
  907.   ex:=first.next;
  908.   WHILE ex#NIL DO
  909.     IF ex IS Negation THEN
  910.       INC(len,Negation(ex).of.StringLen()+1);
  911.     ELSE
  912.       INC(len,ex.StringLen()+1);
  913.     END;
  914.     ex:=ex.next;
  915.   END;
  916.   RETURN len;
  917. END StringLen;
  918.  
  919. METHOD Summation.AppendOn(VAR str : STRING);
  920. VAR ex : Expression;
  921. BEGIN
  922.   first.AppendOn(str);
  923.   ex:=first.next;
  924.   WHILE ex#NIL DO
  925.     IF ex IS Negation THEN
  926.       Strings.Append(str,"-");
  927.       Negation(ex).of.AppendOn(str);
  928.     ELSE
  929.       Strings.Append(str,"+");
  930.       ex.AppendOn(str);
  931.     END;
  932.     ex:=ex.next;
  933.   END;
  934. END AppendOn;
  935.  
  936. METHOD Product.Eval():LONGREAL;
  937. VAR val : LONGREAL;
  938.     e   : Expression;
  939. BEGIN
  940.   val:=1.0;
  941.   e:=first;
  942.   WHILE e#NIL DO val:=val*e.Eval();e:=e.next END;
  943.   RETURN val;
  944. END Eval;
  945.  
  946.  
  947. METHOD Product.StringLen():INTEGER;
  948. VAR len : INTEGER;
  949.     ex  : Expression;
  950. BEGIN
  951.   IF first IS Summation THEN
  952.     len:=first.StringLen()+2;
  953.   ELSE
  954.     len:=first.StringLen();
  955.   END;
  956.   ex:=first.next;
  957.   WHILE ex#NIL DO
  958.     IF ex IS Reciproke THEN
  959.       IF Reciproke(ex).of IS Summation THEN
  960.         INC(len,Reciproke(ex).of.StringLen()+3);
  961.       ELSE
  962.         INC(len,Reciproke(ex).of.StringLen()+1);
  963.       END;
  964.     ELSE
  965.       IF ex IS Summation THEN
  966.         INC(len,ex.StringLen()+3);
  967.       ELSE
  968.         INC(len,ex.StringLen()+1);
  969.       END;
  970.     END;
  971.     ex:=ex.next;
  972.   END;
  973.   RETURN len;
  974. END StringLen;
  975.  
  976. METHOD Product.AppendOn(VAR str : STRING);
  977. VAR ex : Expression;
  978. BEGIN
  979.   IF first IS Summation THEN
  980.     Strings.Append(str,"(");
  981.     first.AppendOn(str);
  982.     Strings.Append(str,")");
  983.   ELSE
  984.     first.AppendOn(str);
  985.   END;
  986.   ex:=first.next;
  987.   WHILE ex#NIL DO
  988.     IF ex IS Reciproke THEN
  989.       Strings.Append(str,"/");
  990.       IF Reciproke(ex).of IS Summation THEN
  991.         Strings.Append(str,"(");
  992.         Reciproke(ex).of.AppendOn(str);
  993.         Strings.Append(str,")");
  994.       ELSE
  995.         Reciproke(ex).of.AppendOn(str);
  996.       END;
  997.     ELSE
  998.       Strings.Append(str,"*");
  999.       IF ex IS Summation THEN
  1000.         Strings.Append(str,"(");
  1001.         ex.AppendOn(str);
  1002.         Strings.Append(str,")");
  1003.       ELSE
  1004.         ex.AppendOn(str);
  1005.       END
  1006.     END;
  1007.     ex:=ex.next;
  1008.   END;
  1009. END AppendOn;
  1010.  
  1011. METHOD SimpleFunction.Create(func : Function;
  1012.                              of   : Expression):Expression;
  1013. BEGIN
  1014.   SELF.of:=of;
  1015.   FORGET SUPER.Create(func);
  1016.   IF of IS Constant THEN
  1017.     Constant(of).value:=SELF.Eval();
  1018.     DISPOSE(SELF);
  1019.     RETURN of
  1020.   ELSE
  1021.     RETURN SELF
  1022.   END;
  1023. END Create;
  1024.  
  1025. METHOD Negation.Eval():LONGREAL;
  1026. BEGIN
  1027.   RETURN -of.Eval();
  1028. END Eval;
  1029.  
  1030. METHOD Negation.Diff(func : Function;after : Variable):Expression;
  1031. VAR dif : Expression;
  1032. BEGIN
  1033.   dif:=of.Diff(func,after);
  1034.   IF dif IS Constant THEN
  1035.     Constant(dif).value:=-Constant(dif).value;
  1036.     RETURN dif
  1037.   ELSE
  1038.     RETURN Negation.Create(func,dif)
  1039.   END;
  1040. END Diff;
  1041.  
  1042. METHOD Negation.StringLen():INTEGER;
  1043. BEGIN
  1044.   IF of IS Summation THEN
  1045.     RETURN of.StringLen()+3
  1046.   ELSE
  1047.     RETURN of.StringLen()+1
  1048.   END;
  1049. END StringLen;
  1050.  
  1051. METHOD Negation.AppendOn(VAR str : STRING);
  1052. BEGIN
  1053.   IF of IS Summation THEN
  1054.     Strings.Append(str,"-(");
  1055.     of.AppendOn(str);
  1056.     Strings.Append(str,")");
  1057.   ELSE
  1058.     Strings.Append(str,"-");
  1059.     of.AppendOn(str);
  1060.   END;
  1061. END AppendOn;
  1062.  
  1063. METHOD Reciproke.Eval():LONGREAL;
  1064. VAR val : LONGREAL;
  1065. BEGIN
  1066.   val:=of.Eval();
  1067.   ASSERT(val#0.0,DivisionByZero);
  1068.   RETURN 1.0/of.Eval();
  1069. END Eval;
  1070.  
  1071. METHOD Reciproke.Diff(func : Function;after : Variable):Expression;
  1072. BEGIN
  1073.   RETURN Negation.Create(func,
  1074.            BuildProduct(func,of.Diff(func,after),
  1075.              Reciproke.Create(func,
  1076.                Potenz.Create(func,of.FClone(func),Constant.Create(func,2.0)))));
  1077. END Diff;
  1078.  
  1079. METHOD Reciproke.StringLen():INTEGER;
  1080. BEGIN
  1081.   IF (of IS Summation) OR (of IS Product) THEN
  1082.     RETURN of.StringLen()+4
  1083.   ELSE
  1084.     RETURN of.StringLen()+2
  1085.   END;
  1086. END StringLen;
  1087.  
  1088. METHOD Reciproke.AppendOn(VAR str : STRING);
  1089. BEGIN
  1090.   IF (of IS Summation) OR (of IS Product) THEN
  1091.     Strings.Append(str,"1/(");
  1092.     of.AppendOn(str);
  1093.     Strings.Append(str,")");
  1094.   ELSE
  1095.     Strings.Append(str,"1/");
  1096.     of.AppendOn(str);
  1097.   END;
  1098. END AppendOn;
  1099.  
  1100. METHOD Potenz.Create(func    : Function;
  1101.                      base,ex : Expression):Expression;
  1102. BEGIN
  1103.   IF (ex IS Constant) AND (Constant(ex).value=0.0) THEN
  1104.     base.Delete;
  1105.     ex.Delete;
  1106.     DISPOSE(SELF);
  1107.     RETURN Constant.Create(func,1.0);
  1108.   OR_IF (base IS Constant) AND ((Constant(base).value=1.0) OR
  1109.                                 (Constant(base).value=0.0)) THEN
  1110.     ex.Delete;
  1111.     DISPOSE(SELF);
  1112.     RETURN base;
  1113.   OR_IF (ex IS Constant) AND (Constant(ex).value=1.0) THEN
  1114.     ex.Delete;
  1115.     DISPOSE(SELF);
  1116.     RETURN base;
  1117.   OR_IF (base IS Constant) AND (ex IS Constant) THEN
  1118.     Constant(base).value:=Constant(base).value^Constant(ex).value;
  1119.     ex.Delete;
  1120.     DISPOSE(SELF);
  1121.     RETURN base;
  1122.   ELSE
  1123.     SELF.base:=base;
  1124.     SELF.exponent:=ex;
  1125.     RETURN SUPER.Create(func);
  1126.   END;
  1127. END Create;
  1128.  
  1129. METHOD Potenz.Eval():LONGREAL;
  1130. BEGIN
  1131.   RETURN base.Eval()^exponent.Eval();
  1132. END Eval;
  1133.  
  1134. METHOD Potenz.Diff(func : Function;after : Variable):Expression;
  1135. BEGIN
  1136.   RETURN BuildSum(func,
  1137.            BuildProduct(func,
  1138.              BuildProduct(func,Potenz.Create(func,base.FClone(func),
  1139.                                                   exponent.FClone(func)),
  1140.                                exponent.Diff(func,after)),
  1141.                                F_LN.Create(func,base.FClone(func))),
  1142.            BuildProduct(func,
  1143.              BuildProduct(func,base.Diff(func,after),
  1144.                              exponent.FClone(func)),
  1145.                              Potenz.Create(func,base.FClone(func),
  1146.                                BuildSum(func,exponent.FClone(func),
  1147.                                              Constant.Create(func,-1)))));
  1148. END Diff;
  1149.  
  1150. METHOD Potenz.StringLen():INTEGER;
  1151. VAR len : INTEGER;
  1152. BEGIN
  1153.   len:=base.StringLen()+exponent.StringLen()+1;
  1154.   IF (base IS Summation) OR (base IS Product) OR (base IS Potenz) THEN
  1155.     INC(len,2);
  1156.   END;
  1157.   IF (exponent IS Summation) OR (exponent IS Product) OR (exponent IS Potenz) THEN
  1158.     INC(len,2);
  1159.   END;
  1160.   RETURN len;
  1161. END StringLen;
  1162.  
  1163. METHOD Potenz.AppendOn(VAR str : STRING);
  1164. BEGIN
  1165.   IF (base IS Summation) OR (base IS Product) OR (base IS Potenz) THEN
  1166.     Strings.Append(str,"(");
  1167.     base.AppendOn(str);
  1168.     Strings.Append(str,")");
  1169.   ELSE
  1170.     base.AppendOn(str);
  1171.   END;
  1172.   Strings.Append(str,"^");
  1173.   IF (exponent IS Summation) OR (exponent IS Product) OR (exponent IS Potenz) THEN
  1174.     Strings.Append(str,"(");
  1175.     exponent.AppendOn(str);
  1176.     Strings.Append(str,")");
  1177.   ELSE
  1178.     exponent.AppendOn(str);
  1179.   END;
  1180. END AppendOn;
  1181.  
  1182. METHOD Variable.Create(    func : Function;
  1183.                        REF name : STRING);
  1184. BEGIN
  1185.   Resources.ChangeObjContext(SELF,func.con);
  1186.   SELF.name:=name;
  1187.   func.varDict.Add(name,SELF);
  1188. END Create;
  1189.  
  1190. METHOD Variable.FClone(func : Function):Expression;
  1191. BEGIN
  1192.   RETURN func.varDict.Search(name);
  1193. END FClone;
  1194.  
  1195. METHOD Function.Create(REF str     : STRING;
  1196.                            context : ContextPtr;
  1197.                        REF vars    : LIST OF STRING);
  1198.  
  1199.   VAR self : Function;
  1200.  
  1201.   VAR
  1202.     cpos : INTEGER;
  1203.     act  : CHAR;
  1204.  
  1205.   PROCEDURE Next;
  1206.   BEGIN
  1207.     ASSERT(cpos<=str.len,SyntaxError);
  1208.     INC(cpos);
  1209.     act:=str.data[cpos];
  1210.   END Next;
  1211.  
  1212.   PROCEDURE Init;
  1213.   BEGIN
  1214.     cpos:=0;
  1215.     act:=str.data[0]
  1216.   END Init;
  1217.  
  1218.   PROCEDURE ParseSumme():Expression;
  1219.  
  1220.     PROCEDURE ParseProduct():Expression;
  1221.  
  1222.       PROCEDURE ParsePotenz():Expression;
  1223.  
  1224.         PROCEDURE ParseItem():Expression;
  1225.         VAR ex,hlp : Expression;
  1226.             str    : STRING(40);
  1227.         BEGIN
  1228.           IF KEY act
  1229.             OF "0".."9" THEN
  1230.               str.len:=0;
  1231.               WHILE act OF "0".."9" DO
  1232.                 str.data[str.len]:=act;INC(str.len);Next
  1233.               END;
  1234.               IF act="." THEN
  1235.                 str.data[str.len]:=act;INC(str.len);Next;
  1236.                 WHILE act OF "0".."9" DO
  1237.                   str.data[str.len]:=act;INC(str.len);Next
  1238.                 END;
  1239.               END;
  1240.               IF act OF "e","E" THEN
  1241.                 str.data[str.len]:=act;INC(str.len);Next;
  1242.                 IF act="-" THEN
  1243.                   str.data[str.len]:=act;INC(str.len);Next;
  1244.                 END;
  1245.                 WHILE act OF "0".."9" DO
  1246.                   str.data[str.len]:=act;INC(str.len);Next
  1247.                 END;
  1248.               END;
  1249.               str.data[str.len]:=&0;
  1250.               ex:=Constant.Create(self,StringToReal(str));
  1251.             END
  1252.             OF "("      THEN
  1253.               Next;
  1254.               ex:=ParseSumme();
  1255.               ASSERT(act=")",SyntaxError);
  1256.               Next;
  1257.             END
  1258.             OF "-"      THEN
  1259.               Next;
  1260.               hlp:=ParseItem();
  1261.               IF hlp IS Constant THEN
  1262.                 ex:=hlp;
  1263.                 Constant(ex).value:=-Constant(ex).value
  1264.               ELSE
  1265.                 ex:=Negation.Create(self,hlp);
  1266.               END;
  1267.             END
  1268.             OF "a".."z",
  1269.                "A".."Z" THEN
  1270.               str.len:=0;
  1271.               WHILE act OF "a".."z","A".."Z","0".."9" DO
  1272.                 str.data[str.len]:=act;INC(str.len);Next
  1273.               END;
  1274.               str.data[str.len]:=&0;
  1275.               IF    CapsEqual(str,"SIN")  THEN
  1276.                 ASSERT(act="(",SyntaxError);Next;
  1277.                 ex:=F_SIN.Create(self,ParseSumme());
  1278.                 ASSERT(act=")",SyntaxError);Next
  1279.               OR_IF CapsEqual(str,"COS")  THEN
  1280.                 ASSERT(act="(",SyntaxError);Next;
  1281.                 ex:=F_COS.Create(self,ParseSumme());
  1282.                 ASSERT(act=")",SyntaxError);Next
  1283.               OR_IF CapsEqual(str,"EXP")  THEN
  1284.                 ASSERT(act="(",SyntaxError);Next;
  1285.                 ex:=F_EXP.Create(self,ParseSumme());
  1286.                 ASSERT(act=")",SyntaxError);Next
  1287.               OR_IF CapsEqual(str,"SQRT") THEN
  1288.                 ASSERT(act="(",SyntaxError);Next;
  1289.                 ex:=F_SQRT.Create(self,ParseSumme());
  1290.                 ASSERT(act=")",SyntaxError);Next
  1291.               OR_IF CapsEqual(str,"LOG")  THEN
  1292.                 ASSERT(act="(",SyntaxError);Next;
  1293.                 ex:=F_LOG.Create(self,ParseSumme());
  1294.                 ASSERT(act=")",SyntaxError);Next
  1295.               OR_IF CapsEqual(str,"LN")   THEN
  1296.                 ASSERT(act="(",SyntaxError);Next;
  1297.                 ex:=F_LN.Create(self,ParseSumme());
  1298.                 ASSERT(act=")",SyntaxError);Next
  1299.               OR_IF CapsEqual(str,"TAN")  THEN
  1300.                 ASSERT(act="(",SyntaxError);Next;
  1301.                 ex:=F_TAN.Create(self,ParseSumme());
  1302.                 ASSERT(act=")",SyntaxError);Next
  1303.               OR_IF CapsEqual(str,"ASIN") THEN
  1304.                 ASSERT(act="(",SyntaxError);Next;
  1305.                 ex:=F_ASIN.Create(self,ParseSumme());
  1306.                 ASSERT(act=")",SyntaxError);Next
  1307.               OR_IF CapsEqual(str,"ACOS") THEN
  1308.                 ASSERT(act="(",SyntaxError);Next;
  1309.                 ex:=F_ACOS.Create(self,ParseSumme());
  1310.                 ASSERT(act=")",SyntaxError);Next
  1311.               OR_IF CapsEqual(str,"ABS")  THEN
  1312.                 ASSERT(act="(",SyntaxError);Next;
  1313.                 ex:=F_ABS.Create(self,ParseSumme());
  1314.                 ASSERT(act=")",SyntaxError);Next
  1315.               OR_IF CapsEqual(str,"SGN")  THEN
  1316.                 ASSERT(act="(",SyntaxError);Next;
  1317.                 ex:=F_SGN.Create(self,ParseSumme());
  1318.                 ASSERT(act=")",SyntaxError);Next
  1319.               OR_IF CapsEqual(str,"ATAN") THEN
  1320.                 ASSERT(act="(",SyntaxError);Next;
  1321.                 ex:=F_ATAN.Create(self,ParseSumme());
  1322.                 ASSERT(act=")",SyntaxError);Next
  1323.               ELSE
  1324.                 ex:=Indirection.Create(self,varDict.Search(str));
  1325.               END;
  1326.             END
  1327.           ELSE
  1328.             RAISE(SyntaxError);
  1329.           END;
  1330.           RETURN ex;
  1331.         END ParseItem;
  1332.  
  1333.       VAR help,pot : Expression;
  1334.  
  1335.       BEGIN
  1336.         pot:=ParseItem();
  1337.         WHILE act="^" DO
  1338.           Next;
  1339.           pot:=Potenz.Create(self,pot,ParseItem());
  1340.         END;
  1341.         RETURN pot;
  1342.       END ParsePotenz;
  1343.  
  1344.     VAR const : Constant;
  1345.         prod  : Product;
  1346.         var   : Expression;
  1347.         help  : Expression;
  1348.  
  1349.     BEGIN
  1350.       prod:=NIL;
  1351.       const:=NIL;
  1352.       var:=ParsePotenz();
  1353.       IF var IS Constant THEN const:=var;var:=NIL END;
  1354.       WHILE KEY act
  1355.         OF "*" DO
  1356.           Next;
  1357.           help:=ParsePotenz();
  1358.           IF help IS Constant THEN
  1359.             IF const#NIL THEN
  1360.               const.value:=const.value*Constant(help).value;
  1361.               DISPOSE(help);
  1362.             ELSE
  1363.               const:=help
  1364.             END;
  1365.           OR_IF prod#NIL THEN
  1366.             prod.InsertLast(help);
  1367.           OR_IF var#NIL THEN
  1368.             prod:=Product.Create(self);
  1369.             prod.InsertLast(var);
  1370.             prod.InsertLast(help);
  1371.           ELSE
  1372.             var:=help;
  1373.           END;
  1374.         END
  1375.         OF "/" DO
  1376.           Next;
  1377.           help:=ParsePotenz();
  1378.           IF help IS Constant THEN
  1379.             ASSERT(Constant(help).value#0.0,DivisionByZero);
  1380.             IF const#NIL THEN
  1381.               const.value:=const.value/Constant(help).value;
  1382.               DISPOSE(help);
  1383.             ELSE
  1384.               const:=help;
  1385.               const.value:=1.0/const.value;
  1386.             END;
  1387.           OR_IF prod#NIL THEN
  1388.             prod.InsertLast(Reciproke.Create(self,help));
  1389.           OR_IF var#NIL THEN
  1390.             prod:=Product.Create(self);
  1391.             prod.InsertLast(var);
  1392.             prod.InsertLast(Reciproke.Create(self,help));
  1393.           ELSE
  1394.             var:=Reciproke.Create(self,help);
  1395.           END;
  1396.         END
  1397.       END;
  1398.       IF (const#NIL) AND (const.value=1.0) AND ((prod#NIL) OR (var#NIL)) THEN
  1399.         DISPOSE(const);const:=NIL;
  1400.       END;
  1401.       IF const=NIL THEN
  1402.         IF prod#NIL THEN
  1403.           RETURN prod
  1404.         ELSE
  1405.           RETURN var
  1406.         END
  1407.       ELSE
  1408.         IF prod#NIL THEN
  1409.           prod.InsertLast(const);
  1410.           RETURN prod;
  1411.         OR_IF var#NIL THEN
  1412.           prod:=Product.Create(self);
  1413.           prod.InsertLast(var);
  1414.           prod.InsertLast(const);
  1415.           RETURN prod;
  1416.         ELSE
  1417.           RETURN const;
  1418.         END;
  1419.       END;
  1420.     END ParseProduct;
  1421.  
  1422.  
  1423.   VAR const : Constant;
  1424.       sum   : Summation;
  1425.       var   : Expression;
  1426.       help  : Expression;
  1427.  
  1428.   BEGIN
  1429.     sum:=NIL;
  1430.     const:=NIL;
  1431.     var:=ParseProduct();
  1432.     IF var IS Constant THEN const:=var;var:=NIL END;
  1433.     WHILE KEY act
  1434.       OF "+" DO
  1435.         Next;
  1436.         help:=ParseProduct();
  1437.         IF help IS Constant THEN
  1438.           IF const#NIL THEN
  1439.             const.value:=const.value+Constant(help).value;
  1440.             DISPOSE(help);
  1441.           ELSE
  1442.             const:=help
  1443.           END;
  1444.         OR_IF sum#NIL THEN
  1445.           sum.InsertLast(help);
  1446.         OR_IF var#NIL THEN
  1447.           sum:=Summation.Create(self);
  1448.           sum.InsertLast(var);
  1449.           sum.InsertLast(help);
  1450.         ELSE
  1451.           var:=help;
  1452.         END;
  1453.       END
  1454.       OF "-" DO
  1455.         Next;
  1456.         help:=ParseProduct();
  1457.         IF help IS Constant THEN
  1458.           IF const#NIL THEN
  1459.             const.value:=const.value-Constant(help).value;
  1460.             DISPOSE(help);
  1461.           ELSE
  1462.             const:=help;
  1463.             const.value:=-const.value;
  1464.           END;
  1465.         OR_IF sum#NIL THEN
  1466.           sum.InsertLast(Negation.Create(self,help));
  1467.         OR_IF var#NIL THEN
  1468.           sum:=Summation.Create(self);
  1469.           sum.InsertLast(var);
  1470.           sum.InsertLast(Negation.Create(self,help));
  1471.         ELSE
  1472.           var:=Negation.Create(self,help);
  1473.         END;
  1474.       END
  1475.     END;
  1476.     IF (const#NIL) AND (const.value=0.0) AND ((sum#NIL) OR (var#NIL)) THEN
  1477.       DISPOSE(const);const:=NIL;
  1478.     END;
  1479.     IF const=NIL THEN
  1480.       IF sum#NIL THEN
  1481.         RETURN sum
  1482.       ELSE
  1483.         RETURN var
  1484.       END
  1485.     ELSE
  1486.       IF sum#NIL THEN
  1487.         sum.InsertLast(const);
  1488.         RETURN sum;
  1489.       OR_IF var#NIL THEN
  1490.         sum:=Summation.Create(self);
  1491.         sum.InsertLast(var);
  1492.         sum.InsertLast(const);
  1493.         RETURN sum;
  1494.       ELSE
  1495.         RETURN const;
  1496.       END;
  1497.     END;
  1498.   END ParseSumme;
  1499.  
  1500. VAR i : INTEGER;
  1501. BEGIN
  1502.   self:=SELF;
  1503.   IF context#NIL THEN
  1504.     Resources.ChangeObjContext(SELF,context);
  1505.   END;
  1506.   TRY
  1507.     con:=Resources.Create_Context(context);
  1508.     varDict.Create(con);
  1509.     variables'RANGE:=vars'RANGE;
  1510.     New(variables);
  1511.     FOR i:=0 TO vars'MAX DO
  1512.       variables[i].Create(SELF,vars[i]);
  1513.     END;
  1514.     Init;
  1515.     ex:=ParseSumme();
  1516.     ASSERT(act=&0,SyntaxError);
  1517.   EXCEPT ELSE
  1518.     SELF.Delete;
  1519.   END;
  1520. END Create;
  1521.  
  1522. METHOD Function.Differentiate(    of      : Function;
  1523.                               REF after   : STRING;
  1524.                                   context : ContextPtr);
  1525. VAR i : INTEGER;
  1526. BEGIN
  1527.   IF context#NIL THEN
  1528.     Resources.ChangeObjContext(SELF,context);
  1529.   END;
  1530.   TRY
  1531.     con:=Resources.Create_Context(context);
  1532.     varDict.Create(con);
  1533.     variables'RANGE:=of.variables'RANGE;
  1534.     New(variables);
  1535.     FOR i:=0 TO variables'MAX DO
  1536.       variables[i].Create(SELF,of.variables[i].name);
  1537.     END;
  1538.     ex:=of.ex.Diff(SELF,of.varDict.Search(after));
  1539.   EXCEPT ELSE
  1540.     SELF.Delete;
  1541.   END;
  1542. END Differentiate;
  1543.  
  1544.  
  1545. METHOD Function.Eval(vars : LIST OF LONGREAL):LONGREAL;
  1546. VAR i : INTEGER;
  1547. BEGIN
  1548.   ASSERT(vars'RANGE=variables'RANGE,WrongParamsNum);
  1549.   FOR i:=0 TO vars'MAX DO
  1550.     variables[i].value:=vars[i]
  1551.   END;
  1552.   RETURN ex.Eval();
  1553. END Eval;
  1554.  
  1555. METHOD Function.toString():STRING;
  1556. VAR len : INTEGER;
  1557. BEGIN
  1558.   len:=ex.StringLen();
  1559.   ALLOC_RESULT(len+1);
  1560.   ASSERT(len<RESULT'RANGE,RangeViolation);
  1561.   RESULT:="";
  1562.   ex.AppendOn(RESULT);
  1563. END toString;
  1564.  
  1565. METHOD Function.Delete;
  1566. BEGIN
  1567.   Resources.Delete_Context(con);
  1568. END Delete;
  1569.  
  1570. PROCEDURE CheckFunction(REF str  : STRING;
  1571.                         REF vars : LIST OF STRING):INTEGER;
  1572.   VAR
  1573.     cpos : INTEGER;
  1574.     act  : CHAR;
  1575.  
  1576.   PROCEDURE Next;
  1577.   BEGIN
  1578.     ASSERT(cpos<=str.len,SyntaxError);
  1579.     INC(cpos);
  1580.     act:=str.data[cpos];
  1581.   END Next;
  1582.  
  1583.   PROCEDURE Init;
  1584.   BEGIN
  1585.     cpos:=0;
  1586.     act:=str.data[0]
  1587.   END Init;
  1588.  
  1589.   PROCEDURE ParseSumme;
  1590.  
  1591.     PROCEDURE ParseProduct;
  1592.  
  1593.       PROCEDURE ParsePotenz;
  1594.  
  1595.         PROCEDURE ParseItem;
  1596.         VAR str : STRING(20);
  1597.             i   : INTEGER;
  1598.         BEGIN
  1599.           IF KEY act
  1600.             OF "0".."9" THEN
  1601.               WHILE act OF "0".."9" DO
  1602.                 Next
  1603.               END;
  1604.               IF act="." THEN
  1605.                 Next;
  1606.                 WHILE act OF "0".."9" DO
  1607.                   Next
  1608.                 END;
  1609.               END;
  1610.               IF act OF "e","E" THEN
  1611.                 Next;
  1612.                 IF act="-" THEN
  1613.                   Next;
  1614.                 END;
  1615.                 WHILE act OF "0".."9" DO
  1616.                   Next
  1617.                 END;
  1618.               END;
  1619.             END
  1620.             OF "("      THEN
  1621.               Next;
  1622.               ParseSumme;
  1623.               ASSERT(act=")",SyntaxError);
  1624.               Next;
  1625.             END
  1626.             OF "-"      THEN
  1627.               Next;
  1628.               ParseItem;
  1629.             END
  1630.             OF "a".."z",
  1631.                "A".."Z" THEN
  1632.               str.len:=0;
  1633.               WHILE act OF "a".."z","A".."Z","0".."9" DO
  1634.                 str.data[str.len]:=act;INC(str.len);Next
  1635.               END;
  1636.               str.data[str.len]:=&0;
  1637.               IF CapsEqual(str,"SIN")  OR
  1638.                  CapsEqual(str,"COS")  OR
  1639.                  CapsEqual(str,"EXP")  OR
  1640.                  CapsEqual(str,"SQRT") OR
  1641.                  CapsEqual(str,"LOG")  OR
  1642.                  CapsEqual(str,"LN")   OR
  1643.                  CapsEqual(str,"TAN")  OR
  1644.                  CapsEqual(str,"ASIN") OR
  1645.                  CapsEqual(str,"ACOS") OR
  1646.                  CapsEqual(str,"ABS")  OR
  1647.                  CapsEqual(str,"SGN")  OR
  1648.                  CapsEqual(str,"ATAN") THEN
  1649.                 ASSERT(act="(",SyntaxError);Next;
  1650.                 ParseSumme;
  1651.                 ASSERT(act=")",SyntaxError);Next
  1652.               ELSE
  1653.                 i:=0;
  1654.                 WHILE (i<vars'RANGE) AND NOT Str.Equal(str,vars[i]) DO
  1655.                   INC(i);
  1656.                 END;
  1657.                 ASSERT(i<vars'RANGE,SyntaxError);
  1658.               END;
  1659.             END
  1660.           ELSE
  1661.             RAISE(SyntaxError);
  1662.           END;
  1663.         END ParseItem;
  1664.  
  1665.       BEGIN
  1666.         ParseItem;
  1667.         WHILE act="^" DO
  1668.           Next;
  1669.           ParseItem;
  1670.         END;
  1671.       END ParsePotenz;
  1672.  
  1673.     BEGIN
  1674.       ParsePotenz;
  1675.       WHILE act OF "*","/" DO
  1676.         Next;
  1677.         ParsePotenz;
  1678.       END;
  1679.     END ParseProduct;
  1680.  
  1681.   BEGIN
  1682.     ParseProduct;
  1683.     WHILE act OF "+","-" DO
  1684.       Next;
  1685.       ParseProduct;
  1686.     END;
  1687.   END ParseSumme;
  1688.  
  1689. BEGIN
  1690.   TRY
  1691.     Init;
  1692.     ParseSumme;
  1693.     ASSERT(act=&0,SyntaxError);
  1694.     cpos:=-1;
  1695.   EXCEPT
  1696.     OF SyntaxError THEN END;
  1697.   END;
  1698.   RETURN cpos
  1699. END CheckFunction;
  1700.  
  1701.  
  1702. END OFunctions.
  1703.